package com.css.security.browser.validate.code.impl;

import com.css.common.security.enums.ValidateCodeType;
import com.css.security.core.validate.code.ValidateCode;
import com.css.security.core.validate.code.ValidateCodeRepository;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.ServletWebRequest;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * 基于redis的验证码存取器，避免由于没有session导致无法存取验证码的问题
 *
 * @author hanyx
 * @date 2019/04/17
 */
@Component
public class RedisValidateCodeRepository implements ValidateCodeRepository {

    /**
     * 验证码放入session时的前缀
     */
    private static final String REDIS_KEY_PREFIX = "REDIS_KEY_FOR_CODE_";

    @Resource
    private RedisTemplate<Object, Object> redisTemplate;

    /**
     * 保存验证码
     *
     * @param request
     * @param validateCode
     * @param validateCodeType
     */
    @Override
    public void save(ServletWebRequest request, ValidateCode validateCode, ValidateCodeType validateCodeType) {
        redisTemplate.opsForValue().set(buildKey(request, validateCodeType), validateCode, 30, TimeUnit.MINUTES);
    }

    /**
     * 获取验证码
     *
     * @param request
     * @param validateCodeType
     * @return
     */
    @Override
    public ValidateCode get(ServletWebRequest request, ValidateCodeType validateCodeType) {
        Object value = redisTemplate.opsForValue().get(buildKey(request, validateCodeType));
        return value == null ? null : (ValidateCode) value;
    }

    /**
     * 移除验证码
     *
     * @param request
     * @param validateCodeType
     */
    @Override
    public void remove(ServletWebRequest request, ValidateCodeType validateCodeType) {
        redisTemplate.delete(buildKey(request, validateCodeType));
    }

    /**
     * 组装redis key
     *
     * @param request
     * @param type
     * @return
     */
    private String buildKey(ServletWebRequest request, ValidateCodeType type) {
//        String deviceId = request.getHeader("deviceId");
//        if (StringUtils.isBlank(deviceId)) {
//            throw new ValidateCodeException("请在请求头中携带deviceId参数");
//        }
        return REDIS_KEY_PREFIX + type.toString().toLowerCase() + ":" + request.getSessionId() ;
    }

}
